/**
 * Created by xiaoz on 16/8/13.
 */
define(["utils", "base"], function (utils, baseClass) {
    var Component = function (config) {
        var _this = this;
        this.pos = config.pos || "bottom";
        Component.baseConstructor.call(this, config);
        this.selectedClassName = this.config.itemSelectedClassName || "yy-dropdown-item-selected";
        this.displayMember = this.config.displayMember;
        this.delayLoadData = config.delayLoadData === true;
        if (!this.displayMember) {
            console.error("请设置有效的displayMember");
        }
        this.hasTitle = false;
        this.title = config.title;
        this.hideCb = config.hideCb?config.hideCb:false;
        this.showCb = config.showCb?config.showCb:false;

        // font
        this.hasIcon = false;
        var font = this.config.font || "";
        var font_arr = font.split("_");

        this.datasourceArr = config.datasource || [];
        this.value = this.value || config.value;
        this.$el.addClass("yy-dropdown");
        this.input = $("<input type='text' readonly='readonly' unselectable='on'/>");

        if (this.title) {
            this.hasTitle = true;
            this.input.val(this.title);
        }

        if (font) {
            this.hasIcon = true;
            // this.input.before('<i class="yy-icon-code">');
            var font_family, font_code;

            if (font_arr.length === 2) {
                font_family = font_arr[0];
                font_code = font_arr[1];

                this.iconDom = $('<i class="yy-icon-code yy-menu-icon" data-code="' + font_code + '" data-icon="&#x' + font_code + ';"></i>');
                utils.css(this.iconDom, {fontFamily: font_family});
                if (this.config.style) {
                    utils.css(this.iconDom, {fontSize: this.config.style.fontSize});
                }

                this.$el.prepend(this.iconDom);
            }
        } else {
            this.$el.append(this.input);
        }

        this.$el.bind("click", function (e) {
            if (_this.disabled) {return;}
            e.stopPropagation();
            e.preventDefault();
            // 阻止光标出现
            _this.$el.find('input').blur();
            _this.pageview.pageManager.triggerBodyClickWithoutSelf(_this);
            _this.show();
        });
        this.hasBinData = false;
        var getDataMethodName = config.comKey + "_getdata";
        this.getDataMethod = this.pageview.plugin[getDataMethodName];
        if (!this.getDataMethod) {
            console.error("请在" + getDataMethodName + "方法中进行数据获取");
        }
        this.init();

        var changeMethodName = config.comKey + "_change";
        this.changeMethod = this.pageview.plugin[changeMethodName];

        var beforeChangeMethodName = config.comKey + "_beforechange";
        this.beforeChangeMethod = this.pageview.plugin[beforeChangeMethodName];

        if (!this.hasTitle) {
            this.input.bind("keydown", function (e) {
                if (e.keyCode === 40) {
                    //下
                    e.stopPropagation();
                    e.preventDefault();
                    _this._selectDown();
                } else if (e.keyCode === 38) {
                    e.stopPropagation();
                    e.preventDefault();
                    _this._selectUp();
                    //上
                } else if (e.keyCode === 13 || e.keyCode === 9) {
                    e.stopPropagation();
                    e.preventDefault();
                    _this.hide();
                } else if (e.keyCode === 8) {
                    e.stopPropagation();
                    e.preventDefault();
                }
            });
        }

    }

    utils.extendClass(Component, baseClass);

    Component.prototype.setPos = function () {
        var itempos = this.selectedItem.position();
        var st = this.dropdowninner.scrollTop();
        var pos = itempos.top + st;
        pos -= 56;
        this.dropdowninner.scrollTop(pos);
    };

    Component.prototype._selectDown = function (e) {
        if (this.selectedItem) {
            var next = this.selectedItem.next();
            if (next && next[0]) {
                this.setItemSelected(next[0]);
            }
        }
        this.setPos();
    };
    Component.prototype._selectUp = function (e) {
        if (this.selectedItem) {
            var prev = this.selectedItem.prev();
            if (prev && prev[0]) {
                this.setItemSelected(prev[0]);
            }
        }
        this.setPos();
    };
    Component.prototype.setDataSource = function (datasourceArr) {
        if (!datasourceArr || !(datasourceArr instanceof Array)) {
            console.error("dropdown 需要指定正确的数据类型");
        }
        this.datasourceArr = datasourceArr;
    };


    Component.prototype.setValueByItemData = function (val) {
        val = val || this.config.defaultData || this.datasourceArr[0];
        var primaryKey = this.config.primaryKey;
        if (!this.config.primaryKey) {
            console.error("dropdown 需要制定priamryKey  这样才能保证setValueByItemData设置唯一正确的值");
        }
        if(val===undefined){
            return;
        }
        if (!utils.isJSON(val)) {
            console.log(val);
            console.error("dropdown 设置了priamryKey那么设置value的时候value必须为JSON数组 格式为数据源的单条格式");
        }
        if (this.datasourceArr.length === 0) {
            this.value = val;

            this.valueData = val;
            this.input.val(val[this.displayMember]);
            return;
        }
        var defaultVal = this.datasourceArr[0];
        var selectedInfo;
        for (var key in this.items) {
            var item = this.items[key];
            var data = item.data;
            if (data[primaryKey] == val[primaryKey]) {
                selectedInfo = item;
                break;
            }
            if (data[primaryKey] == defaultVal[primaryKey]) {
                selectedInfo = item;

            }
        }

        if (this.selectedItem) {
            this.selectedItem.removeClass(this.selectedClassName);
        }
        if(!selectedInfo){
            return;
        }
        this.selectedItem = selectedInfo.dom;
        this.valueData = selectedInfo.data;
        this.selectedItem.addClass(this.selectedClassName);
        if (!this.hasTitle) {
            this.input.val(selectedInfo.data[this.displayMember]);
        }
    };

    Component.prototype.setValue = function (val) {

        if (this.config.primaryKey) {
            this.setValueByItemData(val);
            return;
        }

        if (this.datasourceArr.length === 0) {
            this.value = val;
            this.valueData = val;
            if (!this.hasTitle) {
                this.input.val(val);
            }

            return;
        }
        var defaultVal = this.datasourceArr[0][this.displayMember];
        var selectedInfo;
        for (var key in this.items) {
            var item = this.items[key];
            var data = item.data;
            if (data[this.displayMember] == val) {
                selectedInfo = item;

                break;
            }
            if (data[this.displayMember] == defaultVal) {
                selectedInfo = item;

            }
        }

        if (this.selectedItem) {
            this.selectedItem.removeClass(this.selectedClassName);
        }
        this.selectedItem = selectedInfo.dom;
        this.valueData = selectedInfo.data;
        this.selectedItem.addClass(this.selectedClassName);
        if (!this.hasTitle) {
            this.input.val(selectedInfo.data[this.displayMember]);
        }

    };
    Component.prototype.init = function () {
        var _this = this;
        this.dropdown = $("<div class='yy-dropdown-wrap'></div>");
        if (this.config.dropDownStyle) {
            this.dropdown.css(this.config.dropDownStyle);
        }
        this.dropdowninner = $("<div class='yy-dropdown-wrap-inner'></div>");

        this.dropdown.append(this.dropdowninner);
        this.dropdown.bind("click", function (e) {
            _this.itemClick(e);
        });


        this.pageview.$el.append(this.dropdown);
        if (!this.delayLoadData) {
            if (!this.hasBinData) {
                this.initLayout();
            }
        } else {
            if (!this.hasTitle) {
                if (!this.config.defaultData) {
                    console.error("在配置来delayLoadData为true的情况下,需要配置一个defaultData的对象以供控件显示默认值,比如配置defaultData:{'label':‘全部’},当然label为dispalymember");
                }
                this.valueData = this.config.defaultData;

                this.input.val(this.config.defaultData[this.displayMember]);

            }
        }

    };
    Component.prototype.setDefaultData = function(defaultData){   //在didmount方法中调用
        if(this.hasTitle){
            console.log("配置了title 不能设置defaultData")
        }else{
            this.valueData = defaultData;
            this.input.val(defaultData[this.displayMember]);
        }
    };
    Component.prototype.itemClick = function (e) {
        e.stopPropagation();
        e.preventDefault();
        this.setItemSelected(e.target);
        this.hide();
    };
    Component.prototype.setItemSelected = function (item) {
        var itemMark = item.getAttribute("data-item");
        if (itemMark) {
            var itemInfo = this.items[itemMark];
            var _this = this;

            this.valueData = itemInfo.data;
            if (this.beforeChangeMethod) {
                var r = this.beforeChangeMethod.call(this.pageview.plugin, this, {
                    value: val, valData: this.valueData,
                    success: function () {

                        if (_this.selectedItem) {
                            _this.selectedItem.removeClass(_this.selectedClassName);
                        }
                        _this.selectedItem = itemInfo.dom;

                        _this.selectedItem.addClass(_this.selectedClassName);

                        var val = itemInfo.data[_this.displayMember];
                        if (!_this.hasTitle) {
                            _this.input.val(val);
                        }

                        if (_this.changeMethod) {
                            _this.changeMethod.call(_this.pageview.plugin, _this, {
                                value: val,
                                valData: _this.valueData
                            });
                        }

                    }
                });
                if (r === false) {
                    return;
                }
            } else {
                if (this.selectedItem) {
                    this.selectedItem.removeClass(this.selectedClassName);
                }
                this.selectedItem = itemInfo.dom;

                this.selectedItem.addClass(this.selectedClassName);

                var val = itemInfo.data[this.displayMember];
                if (!this.hasTitle) {
                    this.input.val(val);
                }

                if (this.changeMethod) {
                    this.changeMethod.call(this.pageview.plugin, this, {value: val, valData: this.valueData});
                }

            }


        }
    };

    Component.prototype.getValue = function () {
        return this.valueData[this.displayMember];
    };
    Component.prototype.getValueData = function () {
        return this.valueData;
    };

    Component.prototype.hide = function () {
        this.dropdown.css({visibility: "hidden",top:"-1000px"});
        this.hideCb&&this.hideCb();
        this.pageview.pageManager.cancelBodyClick(this.id);
    };

    // 重新设置数据
    Component.prototype.setData = function (data) {
        this.setDataSource(data);

        this.dropdowninner.empty();
        this._createItems();
    };

    Component.prototype._createItems = function () {
        this.items = {};
        var itemClass = "yy-dropdown-item " + (this.config.itemClassName || "yy-dropdown-default-item");
        for (var i = 0, j = this.datasourceArr.length; i < j; i++) {
            var itemMark = "item_" + i;
            var itemdata = this.datasourceArr[i];
            if(!itemdata){
              continue;
            }
            var val = itemdata[this.displayMember];

            var extendClass = "";
            if (this.config.itemClassName && i === 0) {
                extendClass = " " + this.config.itemClassName + "-" + i;
            }

            var item = $("<div title='" + val + "' data-item='" + itemMark + "' class='" + itemClass + extendClass + "'>" + val + "</div>");
            this.items[itemMark] = {dom: item, data: itemdata};
            this.dropdowninner.append(item);
        }
    };

    Component.prototype.reload = function () {
        this.initLayout();
    };

    Component.prototype.initLayout = function () {
        var _this = this;
        this.showLoading();
        this.dropdowninner&&this.dropdowninner.empty();
        this.items={};
        this.getDataMethod.call(this.pageview.plugin, this, {
            success: function (data) {
                _this.hasBinData = true;
                _this.datasourceArr = data;
                if (data.length === 0) {
                    _this.datasourceArr = [_this.config.defaultData];
                }

                _this._createItems();
                _this.hideLoading();
                if (_this.delayLoadData) {
                    _this.showDropDown();
                }

                _this.setValue(_this.value || _this.config.value);

            },
            error: function (e) {
                _this.showLoadingError();
            }
        });
    };

    Component.prototype.showLoading = function () {
        var _this = this;
        if (!this.dropdownLoading) {
            this.dropdownLoading = $("<div class='yy-dropdown-loadingwrap'></div>");
            this.dropdownLoading.append("<div class='yy-dropdown-error'><span>网络错误,点击</span><span>重新加载</span></div>");
            this.dropdownLoading.bind("click", function () {
                _this.reload();
            });
            var dropDownStyle = this.config.dropDownStyle || {};
            var width = dropDownStyle.width;
            if (width) {
                this.dropdownLoading.css({width: width});
            }
            this.pageview.$el.append(this.dropdownLoading);
        }
        this.dropdownLoading.removeClass("yy-dropdown-wrappererror");
        var pos = this.$el.offset();
        var h = this.$el.height();
        var offset = this.config.offset || {x: 0, y: 0};
        var x = offset.x || 0;
        var y = offset.y || 0;
        this.dropdownLoading.css({
            top: (pos.top + h + y + 2) + "px",
            left: (pos.left + x) + "px",
            "visibility": "visible"
        });
        this.dropdownLoading.spin('tiny', '#999');
    };
    Component.prototype.hideLoading = function () {
        this.dropdownLoading.css({"visibility": "hidden"});
    };
    Component.prototype.showLoadingError = function () {
        this.dropdownLoading.addClass("yy-dropdown-wrappererror");
        this.dropdownLoading.spin(false);
    };

    Component.prototype.showDropDown = function () {
        if (this.disabled) {
            return;
        }
        this.showCb&&this.showCb();
        var _this = this;
        var offset = this.config.offset || {x: 0, y: 0};
        var x = offset.x || 0;
        var y = offset.y || 0;

        var pos = this.$el.offset();
        var h = this.$el.height();
        var top = pos.top + h + y + 2;
        var dropDownStyle = this.config.dropDownStyle || {};
        var height = dropDownStyle.height || 0;
        height = isNaN(height) ? 146 : parseInt(height);
        if (this.config.pos === "top") {
            top = pos.top - height;
        }
        this.dropdown.css({top: (top) + "px", left: (pos.left + x) + "px", "visibility": "visible", "zIndex": 1000});
        this.pageview.pageManager.regeistBodyClick(this.id, function () {
            _this.hide();
        });
    };

    Component.prototype.show = function () {
        var _this = this;
        if (this.delayLoadData) {
            if (!this.hasBinData) {
                this.initLayout();
            } else {
                this.showDropDown();
            }
        } else {
            this.showDropDown();
        }

    };

    return Component;
});
